package name.marz.to.go.ahg.core.executer;

import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import name.marz.to.go.ahg.common.util.LogUtil;
import name.marz.to.go.ahg.core.AutoGetterHttpClient;
import name.marz.to.go.ahg.core.checker.Checker;
import name.marz.to.go.ahg.core.exception.UserProcessException;

import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.util.EntityUtils;


public abstract class AbstractPostExecuter<T> extends AbstractExecuter<T> {
	private static final Logger log = Logger.getLogger(AbstractPostExecuter.class.getName());
	
	/**
	 * @param uri
	 * @param client
	 */
	public AbstractPostExecuter(URI uri, AutoGetterHttpClient client ) {
		super(uri,client);
	}
	/**
	 * @param uri
	 * @param client
	 * @param pageName
	 */
	public AbstractPostExecuter(URI uri, AutoGetterHttpClient client,String pageName ) {
		super(uri,client,pageName);
	}
	
	@Override
	public T execute() throws ClientProtocolException, IOException,UserProcessException {
		// リクエスト生成
		HttpPost req = new HttpPost(uri);
		//　リクエストパラメータ設定
		List<NameValuePair> params = getRequestParameters();
		req.setEntity(new UrlEncodedFormEntity(params,charset));
		
		// レスポンスハンドラ生成
		ResponseHandler<T> handler = getResponseHandler();
		//　リクエスト送信
		log.info(pageName+" POST処理中 " + req.getURI());
		log.fine("request entity : " + EntityUtils.toString(req.getEntity(), charset));
		LogUtil.log(Level.FINE,req.getAllHeaders(),"request header");
		LogUtil.log(Level.FINE, client.getCookieStore().getCookies(),"request cookies");
		T rtn = client.execute(req, handler);
		
		// レスポンスのチェック
		getChecker().check(rtn);
		
		return rtn;
	}
	
	protected Checker<T> getChecker() {
		// デフォルトでは何もしないCheckerを返す
		return new Checker<T>() {
			@Override
			public void check(T target) throws UserProcessException {
				return;
			}
		};
	}

	protected abstract List<NameValuePair> getRequestParameters();
	protected abstract ResponseHandler<T> getResponseHandler();

}
